package com.px.project.module.ml.service.impl;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.px.common.dto.BaseQueryDto;
import com.px.project.module.ml.dto.task.TaskConfigDto;
import com.px.project.module.ml.dto.task.TaskConfigUpdateDto;
import com.px.project.module.ml.entity.TaskConfigDao;
import com.px.project.module.ml.entity.TaskTypeDao;
import com.px.project.module.ml.mapper.ITaskConfigMapper;
import com.px.project.module.ml.service.ITaskConfigService;
import com.px.project.module.ml.service.ITaskTypeService;
import com.px.project.module.ml.vo.task.TaskConfigVo;
import com.px.project.module.ml.vo.task.TaskTypeVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.thread.GlobalThreadPool;
import lombok.RequiredArgsConstructor;

/**
 * 物资系统》》任务设置业务逻辑实现
 *
 * @author 品讯科技
 * @date 2024-08
 */
@Service
@RequiredArgsConstructor
public class TaskConfigServiceImpl extends ServiceImpl<ITaskConfigMapper, TaskConfigDao> implements ITaskConfigService {
    private final ITaskTypeService taskTypeService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveOne(TaskConfigDto taskConfig) {
        TaskConfigDao taskConfigDao = BeanUtil.copyProperties(taskConfig, TaskConfigDao.class);
        taskConfigDao.setType(taskConfig.getType().stream().map(String::valueOf).collect(Collectors.joining(StrPool.COMMA)));
        return super.save(taskConfigDao);
    }

    @Override
    public List<TaskConfigVo> listOfAll() {
        QueryWrapper<TaskConfigDao> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().orderByDesc(TaskConfigDao::getCreateTime);
        List<TaskConfigDao> taskConfigs = super.list(queryWrapper);
        return taskConfigs.stream().map(taskConfig -> {
            TaskConfigVo taskConfigVo = BeanUtil.copyProperties(taskConfig, TaskConfigVo.class);
            taskConfigVo.setType(Arrays.stream(taskConfig.getType().split(StrPool.COMMA)).map(Integer::valueOf).collect(Collectors.toList()));
            return taskConfigVo;
        }).collect(Collectors.toList());
    }

    @Override
    public Page<TaskConfigVo> listOfPage(BaseQueryDto<TaskConfigDao> baseQuery) {
        QueryWrapper<TaskConfigDao> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().orderByDesc(TaskConfigDao::getCreateTime);
        Page<TaskConfigDao> page = super.page(baseQuery.toPage(), queryWrapper);
        List<TaskConfigDao> taskConfigs = page.getRecords();
        Page<TaskConfigVo> pages = BeanUtil.copyProperties(page, Page.class);
        List<TaskConfigVo> taskConfigVos = BeanUtil.copyToList(taskConfigs, TaskConfigVo.class);
        Stream<CompletableFuture<Void>> completableFutureStream = taskConfigVos.stream().map(taskConfigVo -> CompletableFuture.runAsync(() -> {
            QueryWrapper<TaskTypeDao> taskTypeDaoQueryWrapper = new QueryWrapper<>();
            taskTypeDaoQueryWrapper.lambda().in(TaskTypeDao::getId, taskConfigVo.getType()).orderByDesc(TaskTypeDao::getCreateTime);
            List<TaskTypeDao> taskTypes = this.taskTypeService.list(taskTypeDaoQueryWrapper);
            taskConfigVo.setTaskTypes(
                taskTypes.stream().map(taskTypeDao -> new TaskTypeVo().setType(Math.toIntExact(taskTypeDao.getId())).setName(taskTypeDao.getName()))
                    .collect(Collectors.toList()));
        }, GlobalThreadPool.getExecutor()));
        CompletableFuture.allOf(completableFutureStream.toArray(CompletableFuture[]::new)).join();
        pages.setRecords(taskConfigVos);
        return pages;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateOne(TaskConfigUpdateDto taskConfigUpdate) {
        TaskConfigDao taskConfigDao = BeanUtil.copyProperties(taskConfigUpdate, TaskConfigDao.class);
        taskConfigDao.setType(taskConfigUpdate.getType().stream().map(String::valueOf).collect(Collectors.joining(StrPool.COMMA)));
        return super.updateById(taskConfigDao);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteOne(Long id) {
        return super.removeById(id);
    }
}